package com.yxhl.zoume.core.func.map.ui.fragment;


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.OvershootInterpolator;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.ViewFlipper;

import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.jakewharton.rxbinding.view.RxView;
import com.yxhl.zoume.R;
import com.yxhl.zoume.UIConstants;
import com.yxhl.zoume.core.specialcar.view.SpecialCarStationMapView;
import com.yxhl.zoume.core.func.map.presenter.location.LocationMapPresenter;
import com.yxhl.zoume.core.func.map.ui.activity.LocationMapActivity;
import com.yxhl.zoume.core.func.map.ui.adapter.LocationMapPOIAdapter;
import com.yxhl.zoume.core.tripsmgmt.info.LocationMapEntrance;
import com.yxhl.zoume.di.component.car.DaggerSpecialCarComponent;
import com.yxhl.zoume.di.component.car.SpecialCarComponent;
import com.yxhl.zoume.di.module.ActivityModule;
import com.yxhl.zoume.di.module.car.SpecialCarModule;
import com.yxhl.zoume.utils.DiskCacheUtils;
import com.yxhl.zoume.utils.LOG;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.OnClick;
import jp.wasabeef.recyclerview.animators.SlideInUpAnimator;
import rx.functions.Action1;


/**
 * Created by sugarya 06/02
 * 选择点点地图
 */
public class LocationMapFragment extends BaseMapFragment
        implements SpecialCarStationMapView, AMap.OnCameraChangeListener, AdapterView.OnItemSelectedListener {

    private static final String TAG = "LocationMapFrag";

    private static final String YI_YANG_CITY = "益阳市";
    private static final String CHANG_SHA_CITY = "长沙市";

    //益阳赫山区政府
    private static final LatLng YI_YANG_LAT_LNG = new LatLng(28.57641, 112.37558);
    //长沙市政府
    private static final LatLng CHANG_SHA_LAT_LNG = new LatLng(28.228209, 112.938814);


    private static final LatLng[] DEFAULT_SHOW_LAT_LNG_ARRAY = new LatLng[]{YI_YANG_LAT_LNG, CHANG_SHA_LAT_LNG};

    private static final float MAP_ZOOM_LEVEL = 14;

    /**
     * 周边搜索当前页
     */
    private static final int CURRENT_PAGE = 0;
    /**
     * ViewFlipper 播放间隔
     */
    private static final int FLIPPER_INTERVAL = 400;


    @BindView(R.id.rl_fragment_location_map_search)
    RelativeLayout mSearchRl;

    @BindView(R.id.spinner_fragment_location_city_search)
    Spinner mCitySpinner;

    @BindView(R.id.ll_fragment_location_search)
    LinearLayout mLocationSearchLl;

    @BindView(R.id.map_include)
    MapView mMapView;

    @BindView(R.id.frame_fragment_location_car)
    FrameLayout mLocationFrame;
    @BindView(R.id.iv_special_car_location_icon)
    ImageView mLocateIv;

    @BindView(R.id.ll_include_poi_container)
    LinearLayout mPOIContainerLl;
    @BindView(R.id.iv_include_transition_loading_icon)
    ImageView mLoadingIv;
    @BindView(R.id.rl_include_transition_loading_root)
    RelativeLayout mLoadingRootRl;
    @BindView(R.id.flipper_include_transition_token)
    ViewFlipper mLoadingFlipper;
    @BindView(R.id.recycler_include_special_car_station_map)
    RecyclerView mRecyclerView;

    //arguments
    @Inject
    LocationMapPresenter mLocationMapPresenter;

    private LocationMapEntrance mEntrance;

    private LocationMapPOIAdapter mPOIAdapter;

    /**
     * 图标定位 POI结果集
     */
    private List<PoiItem> mPoiItemList = new ArrayList<>();

    private Animation mPoiSearchLoadingAnimation;
    /**
     * 搜索栏点击次数
     */
    private int mSearchClickCount;

    /**
     * Spinner数据集
     */
    private List<String> mCityList;
    private ArrayAdapter<String> mSpinnerAdapter;
    private LatLng mCameraChangeLatLng;

    public LocationMapFragment() {
    }

    public static LocationMapFragment newInstance() {
        LocationMapFragment fragment = new LocationMapFragment();
        return fragment;
    }

    public static LocationMapFragment newInstance(LocationMapEntrance entrance) {
        LocationMapFragment fragment = new LocationMapFragment();
        Bundle arguments = new Bundle();
        arguments.putSerializable(UIConstants.LocationMap.ARGUMENT_KEY_LOCATION_MAP_FRAGMENT_ENTRANCE, entrance);
        fragment.setArguments(arguments);
        return fragment;
    }

    private void parseArguments() {
        Bundle arguments = getArguments();
        if (arguments != null) {
            mEntrance = (LocationMapEntrance) arguments.getSerializable(UIConstants.LocationMap.ARGUMENT_KEY_LOCATION_MAP_FRAGMENT_ENTRANCE);
        }
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        parseArguments();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        mLocationMapPresenter.attachView(this);
        setMapListener(mMapView.getMap());
        initSpinner();
        initBottomView();
        initPOISearchLoading();
        return view;
    }

    /**
     * UI状态重置
     */
    public void setInitialStatus() {
        //Spinner数据同步
        String currentSelectCity = ((LocationMapActivity) mActivity).getUserSelectCity();
        setSpinnerSelection(currentSelectCity);
        //toolbar标题
        setupToolbarTitle(mEntrance);
    }

    /**
     * 设置Spinner的显示Item
     *
     * @param spinnerSelection
     */
    private void setSpinnerSelection(String spinnerSelection) {
        int indexOf = mCityList.indexOf(spinnerSelection);
        if (indexOf >= 0) {
            mCitySpinner.setSelection(indexOf);
        } else {
            mCitySpinner.setSelection(mCityList.size() - 1);
        }
    }


    private void setMapListener(AMap aMap) {
        //Map移动／拖动的监听
        mBaseStartMoveToLocation = true;
        aMap.setOnCameraChangeListener(this);
    }

    private void initSpinner() {
        initializeSpinnerAdapterData();

        mSpinnerAdapter = new ArrayAdapter(mActivity, android.R.layout.simple_spinner_item, mCityList);
        mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mCitySpinner.setAdapter(mSpinnerAdapter);
        mCitySpinner.setOnItemSelectedListener(this);

        String locationCity = getExtraLocationCity(mBaseLocationCity);
        setSpinnerSelection(locationCity);

        mCitySpinner.setEnabled(false);
    }

    private void initializeSpinnerAdapterData() {
        if (mCityList == null) {
            mCityList = new ArrayList<>();
        }
        mCityList.clear();
        mCityList.add(YI_YANG_CITY);
        mCityList.add(CHANG_SHA_CITY);

        String extraLocationCity = getExtraLocationCity(mBaseLocationCity);
        if (!TextUtils.isEmpty(extraLocationCity)) {
            mCityList.add(extraLocationCity);
        }
    }

    /**
     * @param basicLocationCity 地图定位判断得出的城市
     * @return
     */
    private String getExtraLocationCity(String basicLocationCity) {
        if (basicLocationCity != null) {
            if (!YI_YANG_CITY.equals(basicLocationCity) && !CHANG_SHA_CITY.equals(basicLocationCity)) {
                return basicLocationCity;
            }
        } else {
            String locationCacheCity = DiskCacheUtils.getInstance(getContext()).getLocationCity();
            if (!YI_YANG_CITY.equals(locationCacheCity) && !CHANG_SHA_CITY.equals(locationCacheCity)) {
                return locationCacheCity;
            }
        }
        return "";
    }

    /**
     * 初始化加载动画
     */
    private void initPOISearchLoading() {
        mLoadingFlipper.setFlipInterval(FLIPPER_INTERVAL);
        mLoadingFlipper.startFlipping();
        mPoiSearchLoadingAnimation = AnimationUtils.loadAnimation(mActivity, R.anim.poi_search_loading);
        mLoadingIv.startAnimation(mPoiSearchLoadingAnimation);
    }

    private void initBottomView() {
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
        mPOIAdapter = new LocationMapPOIAdapter(this, mPoiItemList, layoutManager);

        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setItemAnimator(new SlideInUpAnimator(new OvershootInterpolator(1f)));
        mRecyclerView.setAdapter(mPOIAdapter);
    }

    /**
     * 设置toolbar标题内容
     *
     * @param entrance
     */
    private void setupToolbarTitle(LocationMapEntrance entrance) {
        if (entrance != null) {
            String toolbarTitle;
            switch (entrance) {
                case SPECIAL_CAR_START:
                    toolbarTitle = getString(R.string.special_car_station_depart_header_title);
                    break;
                case SPECIAL_CAR_ARRIVAL:
                    toolbarTitle = getString(R.string.special_car_station_arrival_header_title);
                    break;
                case ZOUME_BUS_START:
                    toolbarTitle = getString(R.string.zoume_bus_location_map_title);
                    break;
                default:
                    toolbarTitle = "";
            }
            ((LocationMapActivity) mActivity).setToolbarTitle(toolbarTitle);
        }
    }

    @Override
    protected void onMapLocationChange() {
        super.onMapLocationChange();
        //更新Spinner的Item
        if (mCityList.size() <= 2) {
            String extraLocationCity = getExtraLocationCity(mBaseLocationCity);
            if (!TextUtils.isEmpty(extraLocationCity)) {
                if (!mCityList.contains(extraLocationCity)) {
                    mCityList.add(extraLocationCity);
                    mSpinnerAdapter.notifyDataSetChanged();
                    mCitySpinner.setSelection(mCityList.size() - 1);
                }
            }
        }
    }

    @OnClick(R.id.ll_fragment_location_search)
    public void onSearchClick(View view) {
        mSearchClickCount++;
        RxView.clicks(view).throttleFirst(500, TimeUnit.MICROSECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                LOG.e(TAG, "onSearchClick call");
                mSearchClickCount = 0;
                searchClickHandler();
            }
        });
        if (mSearchClickCount == 1) {
            mSearchRl.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (mSearchClickCount == 1) {
                        LOG.e(TAG, "onSearchClick postDelayed");
                        searchClickHandler();
                    }
                }
            }, 200);
        }
    }

    /**
     * 响应查询点击
     */
    private void searchClickHandler() {
        LocationMapActivity stationActivity = (LocationMapActivity) mActivity;
        stationActivity.navigateToPOISearchFragment();
    }

    @OnClick(R.id.frame_fragment_location_car)
    public void onLocationIconClick(View view) {
        if (mBaseLocationCity != null) {
            String currentSelectedCity = ((LocationMapActivity) getActivity()).getUserSelectCity();
            if (mBaseLocationCity.equals(currentSelectedCity)) {
                Location location = mMapView.getMap().getMyLocation();
                if (location != null) {
                    animateMoveTo(new LatLng(location.getLatitude(), location.getLongitude()), MAP_ZOOM_LEVEL);
                }
            } else {
                int index = getSpinnerCurrentLocationSelection(mBaseLocationCity, mCityList);
                mCitySpinner.setSelection(index);
            }
        }
    }

    private int getSpinnerCurrentLocationSelection(String currentLocationCity, List<String> cityList) {
        int indexOf = cityList.indexOf(currentLocationCity);
        if (indexOf >= 0) {
            return indexOf;
        }
        return cityList.size() - 1;
    }

    /**
     * 调用spinner.setSelection()也会调用此方法
     *
     * @param parent
     * @param view
     * @param position
     * @param id
     */
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        String currentSelectedCity = mCityList.get(position);
        ((LocationMapActivity) getActivity()).setUserSelectCity(currentSelectedCity);

        if (currentSelectedCity.equals(mBaseLocationCity)) {
            Location location = mMapView.getMap().getMyLocation();
            if (location != null) {
                animateMoveTo(new LatLng(location.getLatitude(), location.getLongitude()), MAP_ZOOM_LEVEL);
            } else {
                if (position <= DEFAULT_SHOW_LAT_LNG_ARRAY.length - 1) {
                    animateMoveTo(DEFAULT_SHOW_LAT_LNG_ARRAY[position], MAP_ZOOM_LEVEL);
                }
            }
        } else {
            if (position <= DEFAULT_SHOW_LAT_LNG_ARRAY.length - 1) {
                animateMoveTo(DEFAULT_SHOW_LAT_LNG_ARRAY[position], MAP_ZOOM_LEVEL);
            }
        }

        searchPOINearBy(mCameraChangeLatLng, currentSelectedCity);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }

    /**
     * 地图拖动监听
     *
     * @param cameraPosition
     */
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
    }

    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        if (cameraPosition != null) {
            mCameraChangeLatLng = cameraPosition.target;
            String currentSelectedCity = ((LocationMapActivity) getActivity()).getUserSelectCity();
            searchPOINearBy(mCameraChangeLatLng, currentSelectedCity);

            mCitySpinner.setEnabled(true);
        }
    }

    /**
     * 查询附近的POI点
     *
     * @param latLng
     */
    private void searchPOINearBy(LatLng latLng, String selectedCity) {
        if (latLng != null) {
            LatLonPoint centerPoint = new LatLonPoint(latLng.latitude, latLng.longitude);
            mLocationMapPresenter.doSearchPOINearBy(mActivity, CURRENT_PAGE, selectedCity, centerPoint);
        }
    }

    @Override
    public void renderPOISearchResult(List<PoiItem> poiItems) {
        closeLoadingAnimation();
        if (mLoadingRootRl != null) {
            mLoadingRootRl.setVisibility(View.GONE);
        }
        mPOIAdapter.notifyItemData(poiItems);
    }

    /**
     * 关闭加载动画
     */
    private void closeLoadingAnimation() {
        if (mPoiSearchLoadingAnimation != null) {
            mPoiSearchLoadingAnimation.cancel();
        }
        if (mLoadingIv != null) {
            mLoadingIv.clearAnimation();
        }

        if (mLoadingFlipper != null) {
            if (mLoadingFlipper.isFlipping()) {
                mLoadingFlipper.stopFlipping();
            }
        }
    }

    @Override
    public void renderPOISearchOnFailure() {
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        LOG.e(TAG, "onDestroyView");
        //1.停止网络,停止动画
        if (mPoiSearchLoadingAnimation != null) {
            mPoiSearchLoadingAnimation.cancel();
            mPoiSearchLoadingAnimation = null;
        }
    }

    @Override
    protected boolean setUpLocationStyle(AMap aMap) {
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_user_location));
        myLocationStyle.radiusFillColor(Color.TRANSPARENT);
        myLocationStyle.strokeColor(Color.TRANSPARENT);
        aMap.setMyLocationStyle(myLocationStyle);
        return true;
    }

    @Override
    protected Marker getLocationMarker(AMap aMap, LatLng latLng) {
        MarkerOptions markerOptions = new MarkerOptions();
        Bitmap iconBmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_xiache_location);
        markerOptions
                .draggable(true)
                .setFlat(true)
                .icon(BitmapDescriptorFactory.fromBitmap(iconBmp))
                .position(latLng)
                .anchor(0.5f, 1);

        // 计算定位图标在屏幕显示的位置
        int centerX = mMapView.getWidth() / 2;
        int centerY = mMapView.getHeight() / 2;
        //屏幕拖动,图标不动
        Marker marker = aMap.addMarker(markerOptions);
        marker.setPositionByPixels(centerX, centerY);

        return marker;
    }

    @Override
    protected float getLocationMapZoomLevel() {
        return MAP_ZOOM_LEVEL;
    }

    @Override
    protected void secondAnimateMove() {

    }

    @Override
    protected void initializeInjector() {
        SpecialCarComponent specialCarComponent = DaggerSpecialCarComponent.builder()
                .appComponent(getAppComponent())
                .activityModule(new ActivityModule(mActivity))
                .specialCarModule(new SpecialCarModule())
                .build();
        specialCarComponent.inject(this);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_location_map;
    }

    @Override
    protected void setupToolBar() {
        setupToolbarTitle(mEntrance);
    }


}
